#pragma once
#include "d3dx11effect.h"
#include "ProxyObject.h"
#include <vector>

class CBaseCamera;

struct SceneDebugData
{
	SceneDebugData()
	{
		reset();
	}

	unsigned int slices;
	unsigned int triangles;

	void reset() {triangles = slices = 0;}
};

class Scene
{
public:
	Scene();
	~Scene();

	HRESULT init(ID3D11Device* pd3dDevice);
	void	updateViewport(float screenH);
	void	release();

	HRESULT render(const CBaseCamera& camera);
	
	const SceneDebugData& getDebugData() const {return _dbgData;}
	
private:

	typedef std::vector<ProxyObject> ProxyObjects;
	typedef std::vector<std::pair<float, float>> PODists;
	typedef std::vector<std::pair<UINT, UINT>> DrawableVerts;

	HRESULT initEffect();
	HRESULT initGeometry();
	HRESULT	initDepthBuffer();
	HRESULT initComputeShader();

	HRESULT doComputeShader(const CBaseCamera& camera, unsigned int& trianglesNum);
	HRESULT doSorting(unsigned int trianglesNum);
	void setSortingConstants( UINT iLevel, UINT iLevelMask, UINT iHeight, UINT iWidth);
	
	//Now all objects must have the same texture
	ProxyObjects _objs;
	PODists	_poDists;
	float	_halfViewH;
	
	D3DXVECTOR3		_sunDir;
	D3DXVECTOR3		_sunColor;

	SceneDebugData _dbgData;

	bool	_isInit;

	ID3D11Device*						_pd3dDevice;
	ID3D11DeviceContext*				_pd3dContext;

	//ComputeShader
	ID3D11ComputeShader*		_pcsCalcSlicesShader, *_pcsCalcTrianglesShader,
								*_pcsBitonicShader, *_pcsTransposeShader, 
								*_pcsZeroSortedDataShader;
	
	ID3D11Buffer*				_pcsVertexBuffer, *_pcsVertexViewBuffer,
								*_pcsSlicesBuffer, *_pcsTrianglesBuffer,
								*_pcsConstFrameBuf, *_pcsConstSortBuf, 
								*_pcsCountCPUBuffer,
								*_pcsSortDataBuf1, *_pcsSortDataBuf2;
	
	ID3D11ShaderResourceView*	_pcsVertexBufferSRV, *_pcsVertexViewBufferSRV, 
								*_pcsSlicesBufferSRV, *_pcsTrianglesBufferSRV,
								*_pcsSortDataBuf1SRV, *_pcsSortDataBuf2SRV;

	ID3D11UnorderedAccessView*	_pcsVertexViewBufferUAV, *_pcsSlicesBufferUAV, 
								*_pcsTrianglesBufferUAV, 
								*_pcsSortDataBuf1UAV, *_pcsSortDataBuf2UAV;

	//PixelShader
	ID3D11Buffer*				_pFrameCBuffer;
	ID3D11ShaderResourceView*	_srvVolumeTex, *_srvVolumeTexNorm;
	ID3DX11Effect*						_pEffect;
	ID3D11Texture3D*					_tex, *_texNorm;
	ID3DX11EffectShaderResourceVariable* _pevVolume, *_pevVolumeNorm, *_pevVertexes,
										*_pevSortedData;

	ID3DX11EffectConstantBuffer			*_pevConstantBuffer;

	ID3D11Texture2D*					_dsb;
	ID3D11DepthStencilView*				_dsbDSV;

	ID3DX11EffectTechnique*              _pTechDrawSlices;
	ID3DX11EffectTechnique*              _pDrawPrismTechnique;
};
